package com.yc.d0725;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

public class JUnit测试框架 {

    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {

        JUnit测试框架 main = new JUnit测试框架();
        main.runTest(new Tester());

    }

    void runTest(Object tester) throws
            InvocationTargetException,  // 反射执行方法内部出现异常
            IllegalAccessException {   // 如果 反射的对象不能访问
        // 甄别被测试的方法
        Method before = getBefore(tester);
        Method after = getAfter(tester);
        List<Method> tests = getTests(tester);
        int success = 0;
        int failure = 0;
        int error = 0;
        for(Method test : tests){
            // 如果有before方法, 执行before
            if (before != null) {
                before.invoke(tester);
            }
            // 执行被测试方法
            // 统计测试结果: 1. 正确,  2.失败(断言失败), 3.异常
            try{
                test.invoke(tester);
                success ++;
            } catch (AssertException e){
                System.out.println(e.getMessage());
                failure ++;
            } catch ( Exception e){
                e.printStackTrace();
                error ++;
            }
            // 如果有after方法, 执行after
            if (after != null) {
                after.invoke(tester);
            }
        }
        // 打印测试结果, 显示测试方法名
    }

    private List<Method> getTests(Object tester) {
        return null;
    }

    private Method getAfter(Object tester) {
        return null;
    }

    private Method getBefore(Object tester) {
        // 通过反射获取全部方法
        Method[] methods = tester.getClass().getMethods();
        for (Method m : methods) {
            if (m.getAnnotation(Before.class) != null) {
                return m;
            }
        }
        return null;
    }

}

class Tester {

    @Before
    public void before() {
        System.out.println("测试开始");
    }

    @After
    public void after() {
        System.out.println("测试结束");
    }

    @Test
    public void test1() {
        int a = 1, b = 2;
        int c = a + b;
        Assert.assertEquals(3, c);
        Assert.assertEquals(4, c);
    }

    @Test
    public void test2() {
        int a = 1, b = 2;
        int c = a * b;
        Assert.assertEquals(2, c);
    }

    @Test
    public void test3() {
        int a = 1/0;
    }

}


@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Test {
}

// 标记每个 测试方法 执行前执行方法
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Before {
}

// 标记每个 测试方法 执行后执行方法
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface After {
}

class Assert {
    public static void assertEquals(Object expect, Object act) throws AssertException {
        if (expect.equals(act) == false) {
            throw new AssertException(String.format("期待值是%s, 实际值是%s", expect, act));
        }
    }
}

class AssertException extends RuntimeException {
    public AssertException(String message) {
        super(message);
    }
}